import { Request, Response } from 'express';
import bannerService from '../services/bannerService';
import { CreateBannerRequest, UpdateBannerRequest, BannerQueryParams } from '../types/banner';
import { AppError } from '../utils/errors';
import logger from '../utils/logger';

/**
 * @swagger
 * components:
 *   schemas:
 *     Banner:
 *       $ref: '#/components/schemas/Banner'
 *     CreateBannerRequest:
 *       $ref: '#/components/schemas/CreateBannerRequest'
 *     UpdateBannerRequest:
 *       $ref: '#/components/schemas/UpdateBannerRequest'
 *     BannerListResponse:
 *       $ref: '#/components/schemas/BannerListResponse'
 *     BannerStatsResponse:
 *       $ref: '#/components/schemas/BannerStatsResponse'
 */

export class BannerController {
  /**
   * @swagger
   * /api/banners:
   *   post:
   *     summary: 创建轮播图
   *     tags: [轮播图管理]
   *     security:
   *       - bearerAuth: []
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             $ref: '#/components/schemas/CreateBannerRequest'
   *     responses:
   *       201:
   *         description: 轮播图创建成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 轮播图创建成功
   *                 data:
   *                   $ref: '#/components/schemas/Banner'
   *       400:
   *         description: 请求参数错误
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 400
   *                 message:
   *                   type: string
   *                   example: 标题、图片、开始时间和结束时间为必填项
   *       401:
   *         description: 未授权
   *       500:
   *         description: 服务器内部错误
   */
  async createBanner(req: Request, res: Response): Promise<void> {
    try {
      const data: CreateBannerRequest = req.body;
      
      // 基本验证
      if (!data.title || !data.image || !data.startTime || !data.endTime) {
        throw new AppError('标题、图片、开始时间和结束时间为必填项', 400);
      }

      const banner = await bannerService.createBanner(data);
      
      res.status(201).json({
        code: 200,
        message: '轮播图创建成功',
        data: banner,
      });
    } catch (error) {
      logger.error('创建轮播图失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }

  /**
   * @swagger
   * /api/banners/{id}:
   *   put:
   *     summary: 更新轮播图
   *     tags: [轮播图管理]
   *     security:
   *       - bearerAuth: []
   *     parameters:
   *       - in: path
   *         name: id
   *         required: true
   *         schema:
   *           type: integer
   *         description: 轮播图ID
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             $ref: '#/components/schemas/UpdateBannerRequest'
   *     responses:
   *       200:
   *         description: 轮播图更新成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 轮播图更新成功
   *                 data:
   *                   $ref: '#/components/schemas/Banner'
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       404:
   *         description: 轮播图不存在
   *       500:
   *         description: 服务器内部错误
   */
  async updateBanner(req: Request, res: Response): Promise<void> {
    try {
      const id = parseInt(req.params.id);
      const data: UpdateBannerRequest = req.body;

      if (isNaN(id)) {
        throw new AppError('无效的轮播图ID', 400);
      }

      const banner = await bannerService.updateBanner(id, data);
      
      res.json({
        code: 200,
        message: '轮播图更新成功',
        data: banner,
      });
    } catch (error) {
      logger.error('更新轮播图失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }

  /**
   * @swagger
   * /api/banners/{id}:
   *   delete:
   *     summary: 删除轮播图
   *     tags: [轮播图管理]
   *     security:
   *       - bearerAuth: []
   *     parameters:
   *       - in: path
   *         name: id
   *         required: true
   *         schema:
   *           type: integer
   *         description: 轮播图ID
   *     responses:
   *       200:
   *         description: 轮播图删除成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 轮播图删除成功
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       404:
   *         description: 轮播图不存在
   *       500:
   *         description: 服务器内部错误
   */
  async deleteBanner(req: Request, res: Response): Promise<void> {
    try {
      const id = parseInt(req.params.id);

      if (isNaN(id)) {
        throw new AppError('无效的轮播图ID', 400);
      }

      await bannerService.deleteBanner(id);
      
      res.json({
        code: 200,
        message: '轮播图删除成功',
      });
    } catch (error) {
      logger.error('删除轮播图失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }

  /**
   * @swagger
   * /api/banners/batch:
   *   delete:
   *     summary: 批量删除轮播图
   *     tags: [轮播图管理]
   *     security:
   *       - bearerAuth: []
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             required:
   *               - ids
   *             properties:
   *               ids:
   *                 type: array
   *                 items:
   *                   type: integer
   *                 description: 要删除的轮播图ID列表
   *                 example: [1, 2, 3]
   *     responses:
   *       200:
   *         description: 轮播图批量删除成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 轮播图批量删除成功
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       500:
   *         description: 服务器内部错误
   */
  async deleteBanners(req: Request, res: Response): Promise<void> {
    try {
      const { ids } = req.body;

      if (!Array.isArray(ids) || ids.length === 0) {
        throw new AppError('请提供要删除的轮播图ID列表', 400);
      }

      const validIds = ids.filter(id => !isNaN(parseInt(id))).map(id => parseInt(id));
      if (validIds.length === 0) {
        throw new AppError('没有有效的轮播图ID', 400);
      }

      await bannerService.deleteBanners(validIds);
      
      res.json({
        code: 200,
        message: '轮播图批量删除成功',
      });
    } catch (error) {
      logger.error('批量删除轮播图失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }

  /**
   * @swagger
   * /api/banners/{id}:
   *   get:
   *     summary: 获取轮播图详情
   *     tags: [轮播图管理]
   *     security:
   *       - bearerAuth: []
   *     parameters:
   *       - in: path
   *         name: id
   *         required: true
   *         schema:
   *           type: integer
   *         description: 轮播图ID
   *     responses:
   *       200:
   *         description: 获取轮播图详情成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 获取轮播图详情成功
   *                 data:
   *                   $ref: '#/components/schemas/Banner'
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       404:
   *         description: 轮播图不存在
   *       500:
   *         description: 服务器内部错误
   */
  async getBannerById(req: Request, res: Response): Promise<void> {
    try {
      const id = parseInt(req.params.id);

      if (isNaN(id)) {
        throw new AppError('无效的轮播图ID', 400);
      }

      const banner = await bannerService.getBannerById(id);
      
      res.json({
        code: 200,
        message: '获取轮播图详情成功',
        data: banner,
      });
    } catch (error) {
      logger.error('获取轮播图详情失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }

  /**
   * @swagger
   * /api/banners:
   *   get:
   *     summary: 获取轮播图列表
   *     tags: [轮播图管理]
   *     security:
   *       - bearerAuth: []
   *     parameters:
   *       - in: query
   *         name: page
   *         schema:
   *           type: integer
   *           default: 1
   *         description: 页码
   *       - in: query
   *         name: limit
   *         schema:
   *           type: integer
   *           default: 10
   *         description: 每页数量
   *       - in: query
   *         name: keyword
   *         schema:
   *           type: string
   *         description: 搜索关键词
   *       - in: query
   *         name: position
   *         schema:
   *           type: integer
   *           enum: [1, 2]
   *         description: 轮播图位置 (1-首页轮播图, 2-分类页轮播图)
   *       - in: query
   *         name: status
   *         schema:
   *           type: integer
   *           enum: [0, 1]
   *         description: 状态 (0-禁用, 1-启用)
   *       - in: query
   *         name: startDate
   *         schema:
   *           type: string
   *           format: date
   *         description: 开始日期
   *       - in: query
   *         name: endDate
   *         schema:
   *           type: string
   *           format: date
   *         description: 结束日期
   *       - in: query
   *         name: sortBy
   *         schema:
   *           type: string
   *           default: sortOrder
   *         description: 排序字段
   *       - in: query
   *         name: sortOrder
   *         schema:
   *           type: string
   *           enum: [ASC, DESC]
   *           default: ASC
   *         description: 排序方向
   *     responses:
   *       200:
   *         description: 获取轮播图列表成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 获取轮播图列表成功
   *                 data:
   *                   $ref: '#/components/schemas/BannerListResponse'
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       500:
   *         description: 服务器内部错误
   */
  async getBannerList(req: Request, res: Response): Promise<void> {
    try {
      // 处理查询参数，支持嵌套的params对象
      const queryParams = req.query.params ? req.query.params as any : req.query;
      
      const params: BannerQueryParams = {
        page: queryParams.page ? parseInt(queryParams.page) : 1,
        limit: queryParams.limit ? parseInt(queryParams.limit) : 10,
        keyword: queryParams.keyword,
        position: queryParams.position ? (parseInt(queryParams.position) as 1 | 2) : undefined,
        status: queryParams.status !== undefined ? (parseInt(queryParams.status) as 0 | 1) : undefined,
        startDate: queryParams.startDate,
        endDate: queryParams.endDate,
        sortBy: queryParams.sortBy || 'sortOrder',
        sortOrder: queryParams.sortOrder || 'ASC',
      };

      const result = await bannerService.getBannerList(params);
      
      res.json({
        code: 200,
        message: '获取轮播图列表成功',
        data: result,
      });
    } catch (error) {
      logger.error('获取轮播图列表失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }

  /**
   * @swagger
   * /api/banners/stats:
   *   get:
   *     summary: 获取轮播图统计信息
   *     tags: [轮播图管理]
   *     security:
   *       - bearerAuth: []
   *     responses:
   *       200:
   *         description: 获取轮播图统计信息成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 获取轮播图统计信息成功
   *                 data:
   *                   $ref: '#/components/schemas/BannerStatsResponse'
   *       401:
   *         description: 未授权
   *       500:
   *         description: 服务器内部错误
   */
  async getBannerStats(req: Request, res: Response): Promise<void> {
    try {
      const stats = await bannerService.getBannerStats();
      
      res.json({
        code: 200,
        message: '获取轮播图统计信息成功',
        data: stats,
      });
    } catch (error) {
      logger.error('获取轮播图统计信息失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }

  /**
   * @swagger
   * /api/public/banners:
   *   get:
   *     summary: 获取前端轮播图列表（公开接口）
   *     tags: [公开接口]
   *     parameters:
   *       - in: query
   *         name: position
   *         schema:
   *           type: integer
   *           enum: [1, 2]
   *         description: 轮播图位置 (1-首页轮播图, 2-分类页轮播图)
   *     responses:
   *       200:
   *         description: 获取轮播图成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 获取轮播图成功
   *                 data:
   *                   type: array
   *                   items:
   *                     type: object
   *                     properties:
   *                       id:
   *                         type: integer
   *                         description: 轮播图ID
   *                       title:
   *                         type: string
   *                         description: 轮播图标题
   *                       imageUrl:
   *                         type: string
   *                         description: 图片URL
   *                       linkUrl:
   *                         type: string
   *                         description: 链接URL
   *                       position:
   *                         type: integer
   *                         description: 位置
   *                       sortOrder:
   *                         type: integer
   *                         description: 排序
   *       400:
   *         description: 请求参数错误
   *       500:
   *         description: 服务器内部错误
   */
  async getPublicBanners(req: Request, res: Response): Promise<void> {
    try {
      const position = req.query.position ? parseInt(req.query.position as string) : undefined;
      
      if (position !== undefined && ![1, 2].includes(position)) {
        throw new AppError('位置参数必须是1或2', 400);
      }

      const result = await bannerService.getPublicBanners(position as 1 | 2);
      
      res.json({
        code: 200,
        message: '获取轮播图成功',
        data: result,
      });
    } catch (error) {
      logger.error('获取前端轮播图列表失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }

  /**
   * @swagger
   * /api/banners/{id}/status:
   *   patch:
   *     summary: 更新轮播图状态
   *     tags: [轮播图管理]
   *     security:
   *       - bearerAuth: []
   *     parameters:
   *       - in: path
   *         name: id
   *         required: true
   *         schema:
   *           type: integer
   *         description: 轮播图ID
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             required:
   *               - status
   *             properties:
   *               status:
   *                 type: integer
   *                 enum: [0, 1]
   *                 description: 状态 (0-禁用, 1-启用)
   *                 example: 1
   *     responses:
   *       200:
   *         description: 轮播图状态更新成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 code:
   *                   type: integer
   *                   example: 200
   *                 message:
   *                   type: string
   *                   example: 轮播图状态更新成功
   *                 data:
   *                   $ref: '#/components/schemas/Banner'
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       404:
   *         description: 轮播图不存在
   *       500:
   *         description: 服务器内部错误
   */
  async updateBannerStatus(req: Request, res: Response): Promise<void> {
    try {
      const id = parseInt(req.params.id);
      const { status } = req.body;

      if (isNaN(id)) {
        throw new AppError('无效的轮播图ID', 400);
      }

      if (![0, 1].includes(status)) {
        throw new AppError('状态值必须是0或1', 400);
      }

      const banner = await bannerService.updateBannerStatus(id, status);
      
      res.json({
        code: 200,
        message: '轮播图状态更新成功',
        data: banner,
      });
    } catch (error) {
      logger.error('更新轮播图状态失败:', error);
      if (error instanceof AppError) {
        res.status(error.statusCode).json({
          code: error.statusCode,
          message: error.message,
        });
      } else {
        res.status(500).json({
          code: 500,
          message: '服务器内部错误',
        });
      }
    }
  }
}

export default new BannerController();